#include "error.h"
#include "lexical.h"
#include <stdio.h>
#include <assert.h>
int warn_num_g = 0; // 警告个数
int err_num_g = 0;  // 错误个数

void show_error_num(void)
{
    printf("warning: %d, error: %d\n", warn_num_g, err_num_g);
}

/*
    打印词法错误
*/

void lex_err(lex_err_code_e code, err_level_e lvl)
{  
    /* 和 lex_err_code_e 一一对应 */
    const char *lex_err_table[] = {
        "标识符过长",           // ID_2_LONG
        "数字过长",             // NUM_2_LONG
        "字符串过长",           // STR_2_LONG
        "多行注释没有正常结束",  // COMMENT_NO_END
        "字符串缺少右引号",     // STR_INCOMPLT
        "字符不完整",           // CHARA_INCOMPLT
        "逻辑或不完整",         // OR_NO_PAIR
        "无法识别的词法记号",    // UNRECOGNIZED_TOKEN
        "字符常量为空",         // EMPTY_CHARA   
        "未知转义字符",         // UNKNOW_ESCAPE_SEQUENCE
    };

    assert(LEX_ERR_CODE_NUM == ARR_ELEM_CNT(lex_err_table));

    const char *level_str;
    if(lvl == ERROR) {
        level_str = HI_RED"error:"CLOSE;
        err_num_g++;
    } else {
        level_str = HI_YEL"warning:"CLOSE;
        warn_num_g++; 
    }
        
    const char *file_name = scanner_get_file_name();
    int line = scanner_get_line_num();
    int col = scanner_get_col_num();
    char ch = scanner_get_cur_ch();

    if (code == ID_2_LONG) {
        printf("%s:%d:%d: %s %s, 仅识别标识符：%s\n", 
            file_name, line, col, level_str, lex_err_table[code], scanner_get_token_id());
    } else if (code == STR_2_LONG) {
        printf("%s:%d:%d: %s %s, 仅识别字符串：%s\n", 
            file_name, line, col, level_str, lex_err_table[code], scanner_get_token_str());
    } else if (code == NUM_2_LONG) {
        printf("%s:%d:%d: %s %s, 仅识别数字：%d\n", 
            file_name, line, col, level_str, lex_err_table[code], scanner_get_token_num());
    } else if (code == UNRECOGNIZED_TOKEN) {
        printf("%s:%d:%d: %s %s:\'%c\'(ASCII:%d)\n", file_name, line, col, level_str,
               lex_err_table[code], ch, ch);
    } else {
        printf("%s:%d:%d: %s %s\n", file_name, line, col, level_str, lex_err_table[code]);
    }
}



/*
	打印语法错误
*/
void syn_err(syn_err_code_e code,  err_level_e lvl)
{
	
	static const char *syn_err_code_tab[]=
	{
		"未知变量",
		"未知数字",
        "缺少 \'=\'",
        "缺少 \';\'"
	};

    const char *level_str;
    if(lvl == ERROR) {
        level_str = HI_RED"error:"CLOSE;
        err_num_g++;
    } else {
        level_str = HI_YEL"warning:"CLOSE;
        warn_num_g++; 
    }
	        
    const char *file_name = scanner_get_file_name();
    int line = scanner_get_line_num();
    int col = scanner_get_col_num();
    char ch = scanner_get_cur_ch();

    if(code == UNKNOW_VAR || code == UNKNOW_NUM) {
        printf("%s:%d:%d: %s %s %s\n", file_name, line, col, level_str, 
                syn_err_code_tab[code], scanner_get_token_name());
    } else {
        printf("%s:%d:%d: %s %s\n", file_name, line, col, level_str, 
                syn_err_code_tab[code]);
    } 
    

}
